<?php


/*
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation, either version 3 of the 
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this program.  If not, see 
 * <http://www.gnu.org/licenses/>.
*/


// no direct access
defined('_JEXEC') or die('Restricted access');


jimport('joomla.application.component.model');


class MedicalSchedulingModelAppointments extends JModel
{
	/**
	 * Initialize an instance of MedicalSchedulingModelAppointments.
	 */
	function __construct()
	{
		parent::__construct();
		global $mainframe;

		$week         = $mainframe->getUserStateFromRequest('ms_appointments.week',         'week',         date('Y-m-d'), 'string');
		$attending_id = $mainframe->getUserStateFromRequest('ms_appointments.attending_id', 'attending_id', 0,             'integer');

		$this->setWeek($week);
		$this->setAttendingId($attending_id);

		$user = JFactory::getUser();
		$this->name = $user->name;
		$this->email = $user->email;
		$this->telephone = '';
		$this->cellphone = '';
		$this->address = '';
		$this->treatment_id = null;
		$this->comments = '';
	}

	var $name;

	var $email;

	var $start_dt;

	var $telephone;

	var $cellphone;

	var $address;

	var $treatment_id;

	var $comments;

	function requestAppointment()
	{
		jimport('joomla.mail.helper');

		$this->name         = trim(JRequest::getString('name'));
		$this->email        = trim(JRequest::getString('email'));
		$this->start_uts    = strtotime(JRequest::getString('start_dt'));
		$this->telephone    = trim(JRequest::getString('telephone'));
		$this->cellphone    = trim(JRequest::getString('cellphone'));
		$this->address      = trim(JRequest::getString('address'));
		$this->attending_id = trim(JRequest::getInt('attending_id'));
		$this->treatment_id = trim(JRequest::getInt('treatment_id'));
		$this->comments     = trim(JRequest::getString('comments'));
		$this->start_dt     = date('Y-m-d H:i:s', $this->start_uts);

		if ('' == $this->name)
			$this->setError(JText::_("Please type your Name."));
		if ('' == $this->email || !JMailHelper::isEmailAddress($this->email))
			$this->setError(JText::_("Please type a valid E-mail address."));
		if ($this->start_uts <= time())
			$this->setError(JText::_("Please select the Date and time for your appointment."));
		if ('' == $this->telephone)
			$this->setError(JText::_("Please type a Telephone number where we can reach you."));
		if ($this->attending_id <= 0)
			$this->setError(JText::_("Please select the Attending you'd like to see."));
		if ($this->treatment_id <= 0)
			$this->setError(JText::_("Please select the Treatment you want to receive."));

		if (count($this->getErrors()) > 0)
			return false;

		$db = JFactory::getDBO();
		$sql = 'select time_span_minutes'
			. "\n	from #__ms_treatments"
			. "\n	where id = $this->treatment_id"
			;
		$db->setQuery($sql);
		$time_span_minutes = $db->loadResult();

		$this->end_uts = $this->start_uts + ($time_span_minutes * 60);
		$this->end_dt  = date('Y-m-d H:i:s', $this->end_uts);

		$sql = 'select count(*)'
			. "\n	from #__ms_appointments"
			. "\n	where (start_dt >= '{$this->start_dt}' and start_dt < '{$this->end_dt}')"
			. "\n		or (end_dt >= '{$this->start_dt}' and end_dt < '{$this->end_dt}')"
			;
		$db->setQuery($sql);
		if ($db->loadResult() > 0)
		{
			$this->setError(JText::sprintf("The treatment you selected requires %d minutes and overlapes with other appointment.", $time_span_minutes));
			return false;
		}

		$isInRange = false;
		$start_minute = (date('H', $this->start_uts) * 60) + date('i', $this->start_uts);
		$end_minute = (date('H', $this->end_uts) * 60) + date('i', $this->end_uts);
		foreach ($this->getAvailableHours() as $range)
		{
			if ($start_minute >= $range->start_minute && $end_minute <= $range->end_minute)
			{
				$isInRange = true;
				break;
			}
		}
		if (!$isInRange)
		{
			$this->setError(JText::sprintf("The treatment you selected requires %d minutes and the attending is not availble at that time.", $time_span_minutes));
			return false;
		}

		$user = JFactory::getUser();

		$sql = 'insert into #__ms_appointments (name, email, telephone, cellphone, address, start_dt, end_dt'
			. "\n		, attending_id, treatment_id, comments, user_id)"
			. "\n	values(" . $db->quote($this->name)
			. "\n		, " . $db->quote($this->email)
			. "\n		, " . $db->quote($this->telephone)
			. "\n		, " . $db->quote($this->cellphone)
			. "\n		, " . $db->quote($this->address)
			. "\n		, " . $db->quote($this->start_dt)
			. "\n		, " . $db->quote($this->end_dt)
			. "\n		, {$this->attending_id}"
			. "\n		, {$this->treatment_id}"
			. "\n		, " . $db->quote($this->comments)
			. "\n		, {$user->id})"
			;
		$db->setQuery($sql);
		return $db->query() !== false;
	}

	/**
	 * Specify the attending that will be displayed.
	 */
	function setAttendingId($attending_id)
	{
		$this->_attending = null;
		$this->_attending_id = (int)$attending_id;
	}

	/**
	 * Specify the week to display.
	 */
	function setWeek($date)
	{
		$week_uts = strtotime($date);
		$this->_week_start = strtotime('-' . date('w', $week_uts) . ' days', $week_uts);
		$this->_week_end = strtotime('+6 days', $this->_week_start);
	}

	function getForm()
	{
		JFilterOutput::objectHTMLSafe($this);
		return $this;
	}

	function getWeek()
	{
		return date('Y-m-d', $this->_week_start);
	}

	function getAttending()
	{
		if (null == $this->_attending)
		{
			if (0 == $this->_attending_id)
			{
				$sql = 'select *'
					. "\n	from #__ms_attendings"
					. "\n	order by firstname, lastname"
					. "\n	limit 1"
					;
			}
			else
			{
				$sql = 'select *'
					. "\n	from #__ms_attendings"
					. "\n	where id = " . $this->_attending_id
					;
			}
			$db = JFactory::getDBO();
			$db->setQuery($sql);
			$this->_attending = $db->loadObject();
		}
		return $this->_attending;
	}

	function getAttendingList()
	{
		if (null == $this->_attending_list)
		{
			$sql = 'select *'
				. "\n	from #__ms_attendings"
				. "\n	where is_enabled <> 0"
				. "\n	order by firstname, lastname"
				;
			$db = JFactory::getDBO();
			$db->setQuery($sql);
			$this->_attending_list = $db->loadObjectList();
		}
		return $this->_attending_list;
	}

	function getTreatmentList()
	{
		if (null == $this->_treatment_list)
		{
			$sql = 'select *'
				. "\n	from #__ms_treatments"
				. "\n	where is_enabled <> 0"
				. "\n	order by name"
				;
			$db = JFactory::getDBO();
			$db->setQuery($sql);
			$this->_treatment_list = $db->loadObjectList();
		}
		return $this->_treatment_list;
	}

	function getDaysInWeek()
	{
		if (null == $this->_days_in_week)
		{
			$attending           = $this->getAttending();
			$count               = ($attending->available_on_saturdays ? 7 : 6);
			$this->_days_in_week = array();
			for ($i = ($attending->available_on_sundays ? 0 : 1); $i < $count; ++$i)
				$this->_days_in_week[] = strtotime("+ $i days", $this->_week_start);
		}
		return $this->_days_in_week;
	}

	function getAppointmentsThisWeek()
	{
		$db        = JFactory::getDBO();
		$user      = JFactory::getUser();
		$attending = $this->getAttending();
		$sql = 'select id, start_dt, end_dt'
			. "\n		, case when user_id = {$user->id} then name else '' end name"
			. "\n	from #__ms_appointments a"
			. "\n	where attending_id = " . $attending->id
			. "\n		and a.start_dt between " . $db->quote(date('Y-m-d 00:00:00'), $this->_week_start) 
				. ' and ' . $db->quote(date('Y-m-d 23:59:59', $this->_week_end))
			;
		$db->setQuery($sql);
		$appointments = array();
		foreach ((array)$db->loadObjectList() as $row)
		{
			JFilterOutput::objectHTMLSafe($appointment);
			$row->start_uts = strtotime($row->start_dt);
			$row->end_uts = strtotime($row->end_dt);
			$row->row_span     = 0;
			$row->start_minute = (date('H', $row->start_uts) * 60) + date('i', $row->start_uts);
			$row->end_minute   = (date('H', $row->end_uts) * 60) + date('i', $row->end_uts);
			$day_of_week       = date('w', $row->start_uts) - 1;
			$minute = $row->start_minute;
			do
			{
				$appointments[$day_of_week][$minute] = $row;
				$minute += $attending->time_span_minutes;
				++$row->row_span;
			}
			while ($minute < $row->end_minute);
		}
		return $appointments;
	}

	function getAvailableHours()
	{
		if (null == $this->_available_hours)
		{
			$attending = $this->getAttending();
			$this->_available_hours = array();
			foreach (preg_split('/\\s*,\\s*/', $attending->available_hours) as $range)
			{
				$range = preg_split('/\\s*-\\s*/', $range);
				$available_hours = new stdClass();
				$available_hours->start_minute = $range[0] * 60;
				$available_hours->end_minute = $range[1] * 60;
				$this->_available_hours[] = $available_hours;
			}
		}
		return $this->_available_hours;
	}

	function getNextWeekLink()
	{
		$uri = JFactory::getURI();
		$uri->setVar('week', date('Y-m-d', strtotime('+1 week', $this->_week_start)));
		return $uri->toString();
	}

	function getPrevWeekLink()
	{
		$uri = JFactory::getURI();
		$uri->setVar('week', date('Y-m-d', strtotime('-1 week', $this->_week_start)));
		return $uri->toString();
	}

	private $_attending_id = 0;

	private $_week_start = null;

	private $_week_end = null;

	private $_attending = null;

	private $_attending_list = null;

	private $_treatment_list = null;

	private $_days_in_week = null;

	private $_available_hours = null;
}


?>
